import { Component, inject, OnInit, OnDestroy, ChangeDetectionStrategy, signal, computed, input, output } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { AuthService } from '@core/auth/auth.service';
import { LoginRequest } from '@shared/models/login.models';
import { AuthUser } from '@shared/models/user.models';
import { selectIsAuthenticated, selectAuthUser } from '@core/auth/auth.selectors';
import { Observable, Subject, firstValueFrom, take } from 'rxjs';
import { select } from '@ngrx/store';
import { jwtDecode } from 'jwt-decode';
import { guid } from '@shared/utils';
import { MockHelpService, MockHttpLog } from '@shared/mock/mock-help.service';
import { PageComponent } from '@shared/components/page.component';

/**
 * 模拟认证组件
 * 展示完整的模拟认证流程，包括登录、状态管理、用户数据联动
 * 作为 Mock 系统的核心功能演示
 */
@Component({
  selector: 'app-mock-auth',
  standalone: true,
  imports: [CommonModule, FormsModule, ReactiveFormsModule],
  templateUrl: './mock-auth.component.html',
  styleUrl: './mock-auth.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MockAuthComponent extends PageComponent implements OnInit, OnDestroy {

  // 输入属性 - 使用 input() 函数
  title = input<string>('模拟认证');
  showTokenInfo = input<boolean>(true);
  
  // 输出属性 - 使用 output() 函数
  loginSuccess = output<AuthUser>();
  loginError = output<string>();

  constructor() {
    super();
  }

  // 依赖注入
  private readonly authService = inject(AuthService);
  private readonly mockHelpService = inject(MockHelpService);
  private readonly destroy$ = new Subject<void>();

  // HTTP 日志 - 直接使用 MockHelpService 的数据
  httpLogs$: Observable<MockHttpLog[]> = this.mockHelpService.httpLogs$;

  // 登录表单控件 - 符合 Angular MDC 规范，添加验证器
  usernameControl = new FormControl('', [
    Validators.required,
    Validators.minLength(3),
    Validators.maxLength(20)
  ]);
  passwordControl = new FormControl('', [
    Validators.required,
    Validators.minLength(6),
    Validators.maxLength(50)
  ]);

  // 模拟用户数据
  mockUsers = [
    { 
      username: 'admin', 
      password: 'admin123', 
      role: 'admin',
      description: '系统管理员，拥有所有权限',
      avatar: this.generateAvatarSVG('A', '#007bff')
    },
    { 
      username: 'user', 
      password: 'user123', 
      role: 'user',
      description: '普通用户，拥有基本权限',
      avatar: this.generateAvatarSVG('U', '#28a745')
    },
    { 
      username: 'demo', 
      password: 'demo123', 
      role: 'demo',
      description: '演示用户，只读权限',
      avatar: this.generateAvatarSVG('D', '#ffc107')
    }
  ];

  // 直接使用 Store 中的认证状态，不重复定义
  isAuthenticated$ = this.store.pipe(select(selectIsAuthenticated));
  currentUser$ = this.store.pipe(select(selectAuthUser));
  
  // 组件本地状态（不需要同步到 Store 的状态）
  loginErrorMessage = signal<string | null>(null);
  tokenInfo = signal<{ token: string | null; isValid: boolean; expiresAt: string | null }>({
    token: null,
    isValid: false,
    expiresAt: null
  });

  // Token 解码信息
  tokenDecoded = signal<{
    header: any;
    payload: any;
    signature: string;
    raw: string;
  } | null>(null);

  // 操作历史
  operationHistory = signal<Array<{
    id: string;
    timestamp: string;
    action: string;
    result: 'success' | 'error' | 'info';
    details: string;
  }>>([]);

  // 计算属性
  operationCount = computed(() => this.operationHistory().length);
  successCount = computed(() => 
    this.operationHistory().filter(op => op.result === 'success').length
  );
  errorCount = computed(() => 
    this.operationHistory().filter(op => op.result === 'error').length
  );

  ngOnInit(): void {
    // 注册表单控件到 PageComponent，实现加载时自动禁用
    this.registerDisableOnLoadFormControl(this.usernameControl);
    this.registerDisableOnLoadFormControl(this.passwordControl);
    
    this.addOperation('组件初始化', 'info', '模拟认证组件已加载');
    this.updateTokenInfo();
  }

  override ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  /**
   * 获取表单控件错误信息
   */
  getControlError(control: FormControl, fieldName: string): string | null {
    if (control.errors && control.touched) {
      if (control.errors['required']) {
        return `${fieldName}是必填项`;
      }
      if (control.errors['minlength']) {
        return `${fieldName}最少需要${control.errors['minlength'].requiredLength}个字符`;
      }
      if (control.errors['maxlength']) {
        return `${fieldName}最多${control.errors['maxlength'].requiredLength}个字符`;
      }
    }
    return null;
  }

  /**
   * 检查表单是否有效
   */
  isFormValid(): boolean {
    return this.usernameControl.valid && this.passwordControl.valid;
  }
  private updateTokenInfo(): void {
    const token = this.authService.getJwtToken();
    const isValid = this.authService.isJwtTokenValid();
    
    this.tokenInfo.set({
      token,
      isValid,
      expiresAt: token ? this.getTokenExpiration(token) : null
    });

    // 解码 Token
    this.decodeToken(token);
  }

  /**
   * 解码 JWT Token
   */
  private decodeToken(token: string | null): void {
    if (!token) {
      this.tokenDecoded.set(null);
      return;
    }

    try {
      const parts = token.split('.');
      if (parts.length !== 3) {
        this.tokenDecoded.set(null);
        return;
      }

      // 解码 Header
      const header = JSON.parse(atob(this.base64UrlDecode(parts[0])));
      
      // 解码 Payload
      const payload = jwtDecode(token);
      
      // 获取 Signature
      const signature = parts[2];

      this.tokenDecoded.set({
        header,
        payload,
        signature,
        raw: token
      });
    } catch (error) {
      this.tokenDecoded.set(null);
    }
  }

  /**
   * Base64 URL 解码
   */
  private base64UrlDecode(str: string): string {
    // 添加填充字符
    str += '='.repeat((4 - str.length % 4) % 4);
    // 转换为标准 base64
    str = str.replace(/-/g, '+').replace(/_/g, '/');
    return str;
  }

  /**
   * 获取 Token 过期时间
   */
  private getTokenExpiration(token: string): string | null {
    try {
      const payload = JSON.parse(atob(token.split('.')[1]));
      return new Date(payload.exp * 1000).toLocaleString();
    } catch {
      return null;
    }
  }

  /**
   * 快速登录（选择预设用户）
   */
  quickLogin(user: any): void {
    this.usernameControl.setValue(user.username);
    this.passwordControl.setValue(user.password);
    this.addOperation('快速登录', 'info', `选择用户: ${user.username}`);
  }

  /**
   * 执行登录
   */
  async performLogin(): Promise<void> {
    // 标记所有控件为已触摸，触发验证
    this.usernameControl.markAsTouched();
    this.passwordControl.markAsTouched();
    
    // 检查表单有效性
    if (!this.isFormValid()) {
      this.loginErrorMessage.set('请检查表单输入');
      return;
    }
    
    const username = this.usernameControl.value;
    const password = this.passwordControl.value;
    
    if (!username || !password) {
      this.loginErrorMessage.set('请输入用户名和密码');
      return;
    }

    this.loginErrorMessage.set(null);

    try {
      this.addOperation('登录请求', 'info', `尝试登录用户: ${username}`);
      
      const loginRequest: LoginRequest = { username, password };
      const response = await firstValueFrom(this.authService.login(loginRequest));
      
      if (response) {
        this.addOperation('登录成功', 'success', `用户 ${username} 登录成功`);
        
        // 清空表单
        this.usernameControl.setValue('');
        this.passwordControl.setValue('');
        this.usernameControl.markAsUntouched();
        this.passwordControl.markAsUntouched();
        
        // 发出登录成功事件
        const user = await firstValueFrom(this.currentUser$);
        if (user) {
          this.loginSuccess.emit(user);
        }
      }
    } catch (error) {
      const errorMessage = `登录失败: ${JSON.stringify(error)}`;
      this.loginErrorMessage.set(errorMessage);
      this.addOperation('登录失败', 'error', errorMessage);
      
      // 发出登录错误事件
      this.loginError.emit(errorMessage);
    }
  }

  /**
   * 执行登出
   */
  performLogout(): void {
    this.authService.logout();
    this.addOperation('登出操作', 'info', '用户已登出');
  }

  /**
   * 刷新 Token
   */
  async refreshToken(): Promise<void> {
    try {
      this.addOperation('Token 刷新', 'info', '开始刷新 Token');
      const response = await firstValueFrom(this.authService.refreshJwtToken());
      
      if (response) {
        this.addOperation('Token 刷新', 'success', 'Token 刷新成功');
        this.updateTokenInfo();
      }
    } catch (error) {
      this.addOperation('Token 刷新', 'error', `Token 刷新失败: ${JSON.stringify(error)}`);
    }
  }

  /**
   * 检查 Token 状态
   */
  checkTokenStatus(): void {
    const token = this.authService.getJwtToken();
    const isValid = this.authService.isJwtTokenValid();
    
    this.addOperation('Token 检查', isValid ? 'success' : 'error', 
      `Token 状态: ${isValid ? '有效' : '无效'}`);
    
    this.updateTokenInfo();
  }

  /**
   * 测试需要认证的请求
   * 这个请求会被拦截器添加 JWT Token
   */
  async testAuthenticatedRequest(): Promise<void> {
    // 检查认证状态
    const isAuthenticated = await firstValueFrom(this.isAuthenticated$);
    
    if (!isAuthenticated) {
      this.addOperation('拦截测试', 'error', '请先登录');
      return;
    }

    try {
      this.addOperation('拦截测试', 'info', '发送需要拦截器添加 JWT Token 的请求');
      
      // 发送一个需要认证的请求
      const response = await firstValueFrom(
        this.authService.getUserProfile()
      );
      
      this.addOperation('拦截测试', 'success', `请求成功，拦截器已添加 JWT Token。用户: ${response.username}`);
      
    } catch (error) {
      // 检查是否是 HTTP 错误响应
      if (error && typeof error === 'object' && 'status' in error) {
        if (error.status === 200) {
          // 状态码 200 不应该被当作错误
          this.addOperation('拦截测试', 'success', '请求成功，拦截器已添加 JWT Token');
        } else {
          this.addOperation('拦截测试', 'error', `请求失败: ${error.status} - ${(error as any).statusText || 'Unknown Error'}`);
        }
      } else {
        this.addOperation('拦截测试', 'error', `请求失败: ${JSON.stringify(error)}`);
      }
    }
  }

  /**
   * 添加操作记录
   */
  private addOperation(action: string, result: 'success' | 'error' | 'info', details: string): void {
    const timestamp = new Date().toLocaleTimeString();
    this.operationHistory.update(history => {
      const newHistory = [{
        id: guid(),
        timestamp,
        action,
        result,
        details
      }, ...history];
      
      // 限制历史记录数量
      return newHistory.slice(0, 20);
    });
  }

  /**
   * 清空操作历史
   */
  clearHistory(): void {
    this.operationHistory.set([]);
    this.addOperation('历史清空', 'info', '操作历史已清空');
  }

  /**
   * 获取用户权限描述
   */
  getUserPermissions(): string[] {
    // 直接使用 Store 中的当前用户状态
    let currentUser: AuthUser | null = null;
    this.currentUser$.pipe(take(1)).subscribe(user => {
      currentUser = user;
    });
    
    if (!currentUser) return [];
    
    // 根据用户名返回权限
    switch ((currentUser as AuthUser).username) {
      case 'admin':
        return ['系统管理', '用户管理', '数据管理', '系统设置'];
      case 'user':
        return ['数据查看', '数据编辑', '个人设置'];
      case 'demo':
        return ['数据查看'];
      default:
        return ['基本权限'];
    }
  }

  /**
   * 生成 SVG 头像
   */
  private generateAvatarSVG(text: string, color: string): string {
    const svg = `
      <svg width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg">
        <circle cx="30" cy="30" r="30" fill="${color}"/>
        <text x="30" y="38" text-anchor="middle" fill="white" font-family="Arial, sans-serif" font-size="24" font-weight="bold">${text}</text>
      </svg>
    `;
    return 'data:image/svg+xml;base64,' + btoa(svg);
  }

  /**
   * 跟踪请求 ID
   */
  trackByLogId(index: number, log: MockHttpLog): string {
    return log.id;
  }

  /**
   * 获取成功请求数量
   */
  getSuccessCount(logs: MockHttpLog[]): number {
    return logs.filter(log => log.response?.status && log.response.status >= 200 && log.response.status < 400).length;
  }

  /**
   * 获取失败请求数量
   */
  getErrorCount(logs: MockHttpLog[]): number {
    return logs.filter(log => log.response?.status && log.response.status >= 400).length;
  }

  /**
   * 跟踪操作 ID
   */
  trackByOperationId(index: number, operation: any): string {
    return operation.timestamp + operation.action;
  }

  /**
   * 获取状态样式类
   */
  getStatusClass(status: number): string {
    if (status >= 200 && status < 300) return 'success';
    if (status >= 300 && status < 400) return 'redirect';
    if (status >= 400 && status < 500) return 'client-error';
    if (status >= 500) return 'server-error';
    return 'unknown';
  }
}
